using System;
using System.Drawing;
using System.Windows.Forms;
using svs.Mobile.BeyondMedia.FeedCore;
using svs.Mobile.BeyondMedia.FeedCore.Helpers;
using svs.Mobile.BeyondMedia.GraphicsAPI;
using svs.Mobile.BeyondMedia.UiCore;

namespace svs.Mobile.BeyondMedia.Controls
{
	/// <summary>
	/// Provide a 2 line listview
	/// </summary>
	internal class CategoryListView : OwnerDrawnList<FeedCategory>
	{
		#region Delegates

		public delegate void CategorySelectedEvent(FeedCategory category);

		#endregion

		private const int FONT_SIZE = 9;
		private Color HighlightColor = SystemColors.InactiveCaption;
		private CategoryList m_CategoryList = new CategoryList();
		private int BorderWidth;

		public CategoryListView()
		{
			// We need a total of 5 rows, so the height is 180/5=36
			Graphics g = CreateGraphics();
			Font font = new Font(Font.Name, FONT_SIZE, FontStyle.Bold);
			// Calc line height to be height of letter A plus 10%
			ItemHeight = (int) (g.MeasureString("A", font).Height* (PlatformDetection.IsPocketPC()?2.3:1.5));
			g.Dispose();
			BorderWidth = PlatformDetection.IsPocketPC() ? 2 : 1;
			font.Dispose();
		}

		public FeedCategory SelectedCategory
		{
			get
			{
				if (SelectedIndex != -1 && m_CategoryList.Count > 0)
				{
					return m_CategoryList[SelectedIndex];
				}
				else
					return null;
			}
			set
			{
				if (value == null)
					return;

				int i = m_CategoryList.IndexOf(value);

				if (SelectedIndex != i)
				{
					SelectedIndex = i;
				}

				EnsureVisible(SelectedIndex);
			}
		}

		public event CategorySelectedEvent CategorySelected;

		public void SetCategories(CategoryList value)
		{
			Clear();
			m_CategoryList.AddRange(value);
			Items.AddRange(value);
			SelectedIndex = 0;
			OnResize(null);
		}

		/// <summary>
		/// Custom OnPaint. This paints the listview items
		/// </summary>
		/// <param name="e"></param>
		protected override void OnPaint(PaintEventArgs e)
		{
			// Get graphics object from bitmap.
			using (Graphics gOffScreen = PrepareOffscreenGraphics())
			{
				// Set the y pos of the current item
				int itemTop = 0;

				// Draw the visible items.
				for (int n = VScrollBar.Value; n <= VScrollBar.Value + DrawCount; n++)
				{
					Rectangle itemArea;
					itemArea = new Rectangle(0,
					                         itemTop,
					                         ClientSize.Width - (VScrollBar.Visible ? VScrollBar.Width : 0),
					                         ItemHeight);

					if (Items.Count == 0 || n < 0 || n > Items.Count - 1)
						break;

					itemArea.Inflate(-4, -3);

					// Get the current MailItem
					FeedCategory category = (FeedCategory) Items[n];

					DrawItemBox(gOffScreen, n == SelectedIndex, itemArea);

					using (Font font = new Font(Font.Name, FONT_SIZE, category.HasUnreadFeeds?FontStyle.Bold:FontStyle.Regular))
					{
						Rectangle nameRect =
							new Rectangle(itemArea.Left, itemArea.Top, itemArea.Width, itemArea.Height);

						StringFormat sf = new StringFormat();
						sf.Alignment = StringAlignment.Center;
						sf.LineAlignment = StringAlignment.Center;
						//Draw the track name
						using (Brush b = new SolidBrush(ForeColor))
						{
							gOffScreen.DrawString(category.Name, font, b, nameRect, sf);
						}
					}

					// Set the next item top to move down the item height
					itemTop += ItemHeight;
				}

				// Now draw the visible list box
				e.Graphics.DrawImage(OffScreen, 0, 0);
			}
		}

		protected override Graphics PrepareOffscreenGraphics()
		{
			Graphics gOffScreen = Graphics.FromImage(OffScreen);
			gOffScreen.Clear(SystemColors.ScrollBar);
			return gOffScreen;
		}

		protected override void OnKeyDown(KeyEventArgs e)
		{
			switch (e.KeyCode)
			{
				case Keys.Return:

					e.Handled = true;
					OnCategorySelected();
					break;

				case Keys.Left:
					OnCancel();
					e.Handled = true;
					break;

				case Keys.Right:
					OnCancel();
					e.Handled = true;
					break;
			}

			if (!e.Handled)
			{
				base.OnKeyDown(e);
			}
		}

		protected override void OnKeyPress(KeyPressEventArgs e)
		{
			if (e.KeyChar == (Char) Keys.Escape)
			{
				e.Handled = true;
				OnCancel();
			}

			FindNextItemStartingWith(e.KeyChar);
		}

		protected override string GetItemText(int ItemIndex)
		{
			FeedCategory f = Items[ItemIndex] as FeedCategory;
			if (f != null)
				return f.Name;

			return string.Empty;
		}

		private void OnCancel()
		{
			SelectedIndex = -1;
			OnCategorySelected();
		}

		protected override void ItemClicked(int i_ItemIndex, int X, int Y, DragHelper.ClickSpeed speed)
		{
			base.ItemClicked(i_ItemIndex, X, Y, speed);

			if (speed == DragHelper.ClickSpeed.Fast)
				OnCategorySelected();
		}

		private void OnCategorySelected()
		{
			if (CategorySelected != null)
			{
				CategorySelected(SelectedCategory);
			}
		}

		protected override void OnPaintBackground(PaintEventArgs e)
		{
			
		}

		/// <summary>
		/// Clears this instance.
		/// </summary>
		public void Clear()
		{
			SelectedIndex = -1;
			m_CategoryList.Clear();
			Items.Clear();
		}

		private void DrawItemBox(Graphics g, bool selected, Rectangle rc)
		{
			if (selected)
			{
				GraphicsHelper.DrawRoundedRectangle(g,
				                                    Color.WhiteSmoke,
																						BorderWidth,
				                                    HighlightColor,
				                                    rc,
				                                    new Size(8, 8));
			}
			else
			{
				GraphicsHelper.DrawRoundedRectangle(g,
				                                    Color.WhiteSmoke,
				                                    1,
				                                    Color.WhiteSmoke,
				                                    rc,
				                                    new Size(8, 8));
			}
		}
	}
}